package com.tj.bo.product.server.services;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.google.common.collect.Lists;
import com.tj.bo.common.conf.config.RedisConfigUtil;
import com.tj.bo.common.conf.constant.RedisKey;
import com.tj.bo.common.conf.util.DateUtils;
import com.tj.bo.product.client.ProductService;
import com.tj.bo.product.client.vo.*;
import com.tj.bo.product.server.dao.MarketOddsConfigDao;
import com.tj.bo.product.server.dao.MarketOddsHistoryDao;
import com.tj.bo.product.server.dao.ProductDao;
import com.tj.bo.product.server.entity.MarketOddsConfigEntity;
import com.tj.bo.product.server.entity.MarketOddsHistoryEntity;
import com.tj.bo.product.server.entity.ProductEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: binary (mr.vencnet@gmail.com)
 * Date: 2020-06-03
 * Time: 14:30
 */
@Service
public class ProductServiceImpl implements ProductService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProductServiceImpl.class);

    @Autowired
    private RedisConfigUtil binaryConfigUtil;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private MarketOddsConfigDao marketOddsConfigDao;
    @Autowired
    private MarketOddsHistoryDao marketOddsHistoryDao;

    @Override
    public ProductListVo getAllActiveProductList() {
        List<Product> products = new ArrayList<>();
        ProductListVo productListVo = new ProductListVo();

        List<ProductEntity> productEntities;
        String productsCacheStr = redisClient.get(RedisKey.BINARY_OPTION_PRODUCT_CACHE_KEY);
        if (StringUtils.isNotEmpty(productsCacheStr)) {
            productEntities = JSONObject.parseArray(productsCacheStr, ProductEntity.class);
        } else {
            productEntities = productDao.getAllProduct();
            if (CollectionUtils.isNotEmpty(productEntities)) {
                redisClient.set(RedisKey.BINARY_OPTION_PRODUCT_CACHE_KEY, JSONObject.toJSONString(productEntities));
            }
        }

        List<Product> dataProducts = this.convertProducts(productEntities);
        for (Product dataProduct : dataProducts) {
            if (!dataProduct.isShowFlag()) {
                continue;
            }
            Product product = new Product();
            product.setName(dataProduct.getName());
            product.setProductCode(dataProduct.getProductCode());
            product.setLogo(dataProduct.getLogo());
            product.setOdds(dataProduct.getOdds());
            product.setDefaultShow(dataProduct.getDefaultShow());
            product.setOpeningTime(dataProduct.getOpeningTime());
            product.setClosingTime(dataProduct.getClosingTime());
            product.setTailNum(dataProduct.getTailNum());
            product.setShowFlag(dataProduct.isShowFlag());
            product.setLocked(dataProduct.isLocked());
            product.setCurrentOdds(dataProduct.getCurrentOdds());
            product.setMiniOdds(dataProduct.getMiniOdds());

            if (!DateUtils.isInTime(dataProduct.getOpeningTime(), dataProduct.getClosingTime())) {
                product.setLocked(true);
            }
            if (DateUtils.isWeekend(new Date()) && product.getProductCode().startsWith("F_")) {
                product.setLocked(true);
            }
            products.add(product);
        }

        productListVo.setProducts(products);
        return productListVo;
    }

    @Override
    public List<Product> getAllProductList() {
        return this.convertProducts(productDao.getAllProduct());
    }

    private List<Product> convertProducts(List<ProductEntity> productEntities) {
        List<Product> products = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(productEntities)) {
            for (ProductEntity entity : productEntities) {
                Product product = new Product();
                BeanUtils.copyProperties(entity, product);
                product.setLocked(entity.getLocked() == 1 ? true : false);
                product.setShowFlag(entity.getShowFlag() == 1 ? true : false);
                products.add(product);
            }
        }
        return products;
    }

    private Product getProduct(String productCode) {
        if (StringUtils.isEmpty(productCode)) {
            return null;
        }

        String productsCacheStr = redisClient.get(RedisKey.BINARY_OPTION_PRODUCT_CACHE_KEY);
        if (StringUtils.isNotEmpty(productsCacheStr)) {
            List<ProductEntity> productEntities = JSONObject.parseArray(productsCacheStr, ProductEntity.class);
            return convertProduct(productEntities.stream().filter(s -> s.getProductCode().equalsIgnoreCase(productCode)).findAny()
                    .orElse(null));
        } else {
            return convertProduct(productDao.getByProductCode(productCode));
        }
    }

    private Product convertProduct(ProductEntity entity) {
        Product product = null;
        if (entity != null) {
            product = new Product();
            BeanUtils.copyProperties(entity, product);
            product.setLocked(entity.getLocked() == 1 ? true : false);
            product.setShowFlag(entity.getShowFlag() == 1 ? true : false);
        }
        return product;
    }

    @Override
    public Product getProductByCode(String productCode) {
        return this.getProduct(productCode);
    }

    @Override
    public ProductGlobalSetting getGlobalSetting(boolean isGrey) {
        String defaultValue = binaryConfigUtil.getOddsGlobalSettingValue();
        ProductGlobalSetting productGlobalSetting = JSON.parseObject(defaultValue, ProductGlobalSetting.class);
        if(isGrey){
            MoneyLimit moneyLimit = JSONObject.parseObject(binaryConfigUtil.getOddsGlobalMoneySetting(), MoneyLimit.class);
            productGlobalSetting.setMoneyLimit(moneyLimit);
        }
        return productGlobalSetting;
    }

    @Override
    public boolean insertMarketOddsHistory(MarketOddsHistory marketOddsHistory) {
        if (marketOddsHistory != null) {
            MarketOddsHistoryEntity entity = new MarketOddsHistoryEntity();
            BeanUtils.copyProperties(marketOddsHistory, entity);
            marketOddsHistoryDao.insert(entity);
        }
        return true;
    }

    @Override
    public List<MarketOddsConfig> getMarketOddsConfigInfo() {

        List<MarketOddsConfig> marketOddsConfigs = Lists.newArrayList();
        String productsCacheStr = redisClient.get(RedisKey.BINARY_OPTION_PRODUCT_ODDS_CONFIG_KEY);
        if (StringUtils.isNotEmpty(productsCacheStr)) {
            marketOddsConfigs = JSONObject.parseArray(productsCacheStr, MarketOddsConfig.class);
            return marketOddsConfigs;
        }
        List<MarketOddsConfigEntity> byMarketOddConfigList = marketOddsConfigDao.getByMarketOddConfigList();
        if (CollectionUtils.isNotEmpty(byMarketOddConfigList)) {
            for (MarketOddsConfigEntity entity : byMarketOddConfigList) {
                MarketOddsConfig marketOddsConfig = new MarketOddsConfig();
                BeanUtils.copyProperties(entity, marketOddsConfig);
                marketOddsConfigs.add(marketOddsConfig);
            }
            redisClient.set(RedisKey.BINARY_OPTION_PRODUCT_ODDS_CONFIG_KEY, JSONObject.toJSONString(byMarketOddConfigList));
        }
        return marketOddsConfigs;
    }

    @Override
    public boolean updateMarketProduct(String variableOdds, String productCode) {
        if (StringUtils.isEmpty(variableOdds)) {
            return false;
        }
        productDao.updateProductByOdds(variableOdds, productCode);
        return true;
    }


    @Override
    public boolean updateProductByOdds(String productCode) {
        productDao.updateProductByInitOdds(productCode);
        return true;
    }

    @Override
    public boolean updateProductByMiniOdds(String productCode) {
        productDao.updateProductByMiniOdds(productCode);
        return true;
    }


    @Override
    public boolean updateProductBasicInfoById(Integer id, Product product) {
        if (id == null) {
            return false;
        }
        ProductEntity productEntity = productDao.selectByPrimaryKey(id.longValue());
        if (productEntity == null) {
            return false;
        }


        if (product.isLocked() != null) {
            productEntity.setLocked(product.isLocked() ? 1 : 0);
        }
        if (product.isShowFlag() != null) {
            productEntity.setShowFlag(product.isShowFlag() ? 1 : 0);
        }

        if (product.getDefaultShow() != null) {
            productEntity.setDefaultShow(product.getDefaultShow());
        }
        if (product.getOdds() != null) {
            productEntity.setOdds(product.getOdds());
        }

        if (product.getMiniOdds() != null) {
            productEntity.setMiniOdds(product.getMiniOdds());
        }
        if (product.getCurrentOdds() != null) {
            productEntity.setCurrentOdds(product.getCurrentOdds());
        }
        if (product.getOpeningTime() != null) {
            productEntity.setOpeningTime(product.getOpeningTime());
        }
        if (product.getClosingTime() != null) {
            productEntity.setClosingTime(product.getClosingTime());
        }

        try {
            productDao.updateByPrimaryKey(productEntity);
        } catch (Exception e) {
            LOGGER.error("== 更新产品基本信息发生错误 ==,Id:{},product:{}", id, JSON.toJSON(product), e);
            return false;
        }

        redisClient.del(RedisKey.BINARY_OPTION_PRODUCT_CACHE_KEY);
        redisClient.del(RedisKey.BINARY_OPTION_PRODUCT_ODDS_CONFIG_KEY);
        return true;
    }

    @Override
    public boolean updateProductBasicInfoByProductCode(String productCode, Product product) {
        if (StringUtils.isEmpty(productCode)) {
            return false;
        }

        ProductEntity byProductCode = productDao.getByProductCode(productCode);
        if (byProductCode == null) {
            return false;
        }

        return updateProductBasicInfoById(byProductCode.getId().intValue(), product);
    }
}
